package com.winit.openapi.apiadapter.controller;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.oms.spi.outbound.OutboundOrderService;
import com.winit.oms.spi.outbound.command.order.OutboundOrderCommand;
import com.winit.oms.spi.outbound.vo.OutboundOrderEnumContants.OrderType;
import com.winit.oms.spi.outbound.vo.OutboundOrderVo;
import com.winit.openapi.apiadapter.adapter.OutboundOrderIntelligentServiceAdapter;
import com.winit.openapi.apiadapter.controller.builder.OrderAdapteBuilder;
import com.winit.openapi.apiadapter.controller.validator.OrderAdapteValidator;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.APISysConfigUtil;
import com.winit.ups.spi.command.CodeCommand;
import com.winit.ups.spi.command.QueryAutoTaketimeCommand;
import com.winit.ups.spi.warehouse.WarehouseService;
import com.winit.ups.spi.warehouse.vo.WarehouseVo;

/**
 * 出库单下单AD接口适配，包含下草稿单，提交单和分销商下单
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * minghao.deng 	1.0  		2017年9月12日 	Created
 *
 * </pre>
 * @since 1.
 */
@Controller
public class OutboundOrderAdapteController extends BaseController {

    private static final Logger                    logger = LoggerFactory.getLogger(OutboundOrderAdapteController.class);

    @Resource
    private WarehouseService                       upsWarehouseService;
    @Resource
    private OutboundOrderIntelligentServiceAdapter outboundOrderIntelligentServiceAdapter;
    @Resource
    private OutboundOrderService                   outboundOrderService;
    @Resource
    private OrderAdapteBuilder                     orderAdapteBuilder;
    @Resource
    private APISysConfigUtil                       apiSysConfigUtil;

    /**
     * 创建出库单：提交单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createOutboundOrder")
    public String createOutboundOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        JSONObject json = JSONObject.parseObject(requestMsg.getData().toString());
        // 数据校验
        OrderAdapteValidator.validCreateOutboundOrder(json);
        OutboundOrderVo vo = orderAdapteBuilder.buildOutboundOrderFromOldAPI(requestMsg);

        //logger.info("createOutboundOrder适配构建VO结果：" + JSONObject.toJSONString(vo));

        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);

        // 获取UMS智能仓库开关接口
        String orderSource = "GFS".equalsIgnoreCase(requestMsg.getPlatform()) ? "GFS" : "API";
        boolean isOpen = outboundOrderIntelligentServiceAdapter.vildaiteIntelligentRecommend(bpartner.getValue(),
            orderSource);
        // 查询智能推荐的仓库编码列表
        List<String> warehouseList = outboundOrderIntelligentServiceAdapter.queryWareHouseByAreaCode(bpartner.getValue());
        //9843 如推荐仓库与下单仓库不一致，支持直接下单成功并返回下单仓库给客户  2017-12-29
        //读取配置的白名单客户的客户编码code
        String whiteAccountCodeStr = apiSysConfigUtil.getConfigValueByKey("API_OUTBOUND_ORDER_INTELLIGENT_WHITE_ACCOUNT");
        List<String> codeList = null;
        if(StringUtils.isNotBlank(whiteAccountCodeStr)){
            String[] codeArray = whiteAccountCodeStr.split("\\,");
            codeList = Arrays.asList(codeArray);
        }
        WarehouseVo intelligentWareHouse = null;
        Map<String, Object> resultMap = new HashMap<String, Object>();
        if (isOpen && CollectionUtils.isNotEmpty(warehouseList)
            && warehouseList.contains(vo.getDispatchWarehouseInfo().getWarehouseCode())) {

            // 记录客人原先选择的仓库和派送方式
            long sourceWarehouseId = json.getLong("warehouseID");
            String sourceDeliveryWayId = vo.getProductInfo().getDeliveryCode();
            String sourceWarehouseCode = vo.getDispatchWarehouseInfo().getWarehouseCode();

            // 智能推荐逻辑
            outboundOrderIntelligentServiceAdapter.getIntelligentRecommendOrder(vo);

            if (!sourceWarehouseCode.equals(vo.getDispatchWarehouseInfo().getWarehouseCode())) {
                CodeCommand codeCommand = new CodeCommand();
                codeCommand.setCode(vo.getDispatchWarehouseInfo().getWarehouseCode());
                intelligentWareHouse = upsWarehouseService.queryWarehouseByCode(codeCommand);
                if (codeList == null || !codeList.contains(bpartner.getValue())) {
                    logger.error("createOutboundOrder error,选择的仓库和推荐的仓库不一致,原仓库ID：" + String.valueOf(sourceWarehouseId)
                                 + ",  原派送方式:" + sourceDeliveryWayId + ";推荐仓库ID："
                                 + String.valueOf(intelligentWareHouse.getWarehouseId()) + ",推荐派送方式："
                                 + vo.getProductInfo().getDeliveryCode());
                    throw new ApiException(ErrorCode.API_INTELLIGENT_WAREHOUSE_ERROR, vo.getDispatchWarehouseInfo()
                        .getWarehouseName(), String.valueOf(intelligentWareHouse.getWarehouseId()), vo.getProductInfo()
                        .getDeliveryCode(), vo.getProductInfo().getWinitProductName());

                }
                logger.info("使用静默智能推荐直接下单，账号：" + requestMsg.getApp_key() + " 客户编码：" + bpartner.getValue() + " 原仓库ID："
                            + String.valueOf(sourceWarehouseId) + ",  原派送方式:" + sourceDeliveryWayId + ";推荐仓库ID："
                            + String.valueOf(intelligentWareHouse.getWarehouseId()) + ",推荐派送方式："
                            + vo.getProductInfo().getDeliveryCode());
                // 开启静默API智能下单的返回推荐仓库和WINIT产品信息
                resultMap.put("recommendWarehouseId", String.valueOf(intelligentWareHouse.getWarehouseId()));
                resultMap.put("recommendWarehouseCode", vo.getDispatchWarehouseInfo().getWarehouseCode());
                resultMap.put("recommendWarehouseName", vo.getDispatchWarehouseInfo().getWarehouseName());
                resultMap.put("recommendDeliveryID", vo.getProductInfo().getDeliveryCode());
                resultMap.put("recommendWinitProductCode", vo.getProductInfo().getWinitProductCode());
                resultMap.put("recommendWinitProductName", vo.getProductInfo().getWinitProductName());
            }
        }
        String orderNo = outboundOrderService.createOrder(validAndBuildOrder(vo));
        resultMap.put("outboundOrderNum", orderNo);
        
        responseMsg.setData(resultMap);

        return API_ADAPTED_SUCCESS;

    }

    /**
     * 创建出库单：草稿单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createOutboundInfo")
    public String createOutboundInfo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        JSONObject json = JSONObject.parseObject(requestMsg.getData().toString());
        // 数据校验
        OrderAdapteValidator.validCreateOutboundOrder(json);
        OutboundOrderVo vo = orderAdapteBuilder.buildOutboundOrderFromOldAPI(requestMsg);

        //logger.info("createOutboundInfo适配构建VO结果：" + JSONObject.toJSONString(vo));

        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        /* 检验商品是否存在退货商品 存在不让下单=============begin by qiuhai.huang */
        if (!OrderAdapteValidator.validateIsRetrunProduct(vo)) {
            throw new ApiException(ErrorCode.API_DRAFT_ORDER_CONTENT_RETURN_PRODUCT_ERROR);
        }
        // 获取UMS智能仓库开关接口
        String orderSource = "GFS".equalsIgnoreCase(requestMsg.getPlatform()) ? "GFS" : "API";
        boolean isOpen = outboundOrderIntelligentServiceAdapter.vildaiteIntelligentRecommend(bpartner.getValue(),
            orderSource);
        // 查询智能推荐的仓库编码列表
        List<String> warehouseList = outboundOrderIntelligentServiceAdapter.queryWareHouseByAreaCode(bpartner.getValue());
      //9843 如推荐仓库与下单仓库不一致，支持直接下单成功并返回下单仓库给客户  2017-12-29
        //读取配置的白名单客户的客户编码code
        String whiteAccountCodeStr = apiSysConfigUtil.getConfigValueByKey("API_OUTBOUND_ORDER_INTELLIGENT_WHITE_ACCOUNT");
        List<String> codeList = null;
        if(StringUtils.isNotBlank(whiteAccountCodeStr)){
            String[] codeArray = whiteAccountCodeStr.split("\\,");
            codeList = Arrays.asList(codeArray);
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        if (isOpen && CollectionUtils.isNotEmpty(warehouseList)
            && warehouseList.contains(vo.getDispatchWarehouseInfo().getWarehouseCode())) {

            // 记录客人原先选择的仓库和派送方式
            long sourceWarehouseId = json.getLong("warehouseID");
            String sourceDeliveryWayId = vo.getProductInfo().getDeliveryCode();
            String sourceWarehouseCode = vo.getDispatchWarehouseInfo().getWarehouseCode();

            // 智能推荐逻辑
            outboundOrderIntelligentServiceAdapter.getIntelligentRecommendOrder(vo);

            if (!sourceWarehouseCode.equals(vo.getDispatchWarehouseInfo().getWarehouseCode())) {
                // 根据传入的派送方式查询出产品
                CodeCommand codeCommand = new CodeCommand();
                codeCommand.setCode(vo.getDispatchWarehouseInfo().getWarehouseCode());
                WarehouseVo intelligentWareHouse = upsWarehouseService.queryWarehouseByCode(codeCommand);
                if (codeList == null || !codeList.contains(bpartner.getValue())) {
                    logger.error("createOutboundOrder error,选择的仓库和推荐的仓库不一致,原仓库ID：" + String.valueOf(sourceWarehouseId)
                                 + ",  原派送方式:" + sourceDeliveryWayId + ";推荐仓库ID："
                                 + String.valueOf(intelligentWareHouse.getWarehouseId()) + ",推荐派送方式："
                                 + vo.getProductInfo().getDeliveryCode());
                    throw new ApiException(ErrorCode.API_INTELLIGENT_WAREHOUSE_ERROR, vo.getDispatchWarehouseInfo()
                        .getWarehouseName(), String.valueOf(intelligentWareHouse.getWarehouseId()), vo.getProductInfo()
                        .getDeliveryCode(), vo.getProductInfo().getWinitProductName());

                }
                logger.info("使用静默智能推荐直接下单，账号：" + requestMsg.getApp_key() + " 客户编码：" + bpartner.getValue() + " 原仓库ID："
                        + String.valueOf(sourceWarehouseId) + ",  原派送方式:" + sourceDeliveryWayId + ";推荐仓库ID："
                        + String.valueOf(intelligentWareHouse.getWarehouseId()) + ",推荐派送方式："
                        + vo.getProductInfo().getDeliveryCode());
                // 开启静默API智能下单的返回推荐仓库和WINIT产品信息
                resultMap.put("recommendWarehouseId", String.valueOf(intelligentWareHouse.getWarehouseId()));
                resultMap.put("recommendWarehouseCode", vo.getDispatchWarehouseInfo().getWarehouseCode());
                resultMap.put("recommendWarehouseName", vo.getDispatchWarehouseInfo().getWarehouseName());
                resultMap.put("recommendDeliveryID", vo.getProductInfo().getDeliveryCode());
                resultMap.put("recommendWinitProductCode", vo.getProductInfo().getWinitProductCode());
                resultMap.put("recommendWinitProductName", vo.getProductInfo().getWinitProductName());
            }
        }
        String orderNo = outboundOrderService.createOrder2Drft(validAndBuildOrder(vo));
        resultMap.put("outboundOrderNum", orderNo);
        responseMsg.setData(resultMap);

        return API_ADAPTED_SUCCESS;
    }

    /**
     * 分销商创建出库单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createOutboundOrderFx")
    public String createOutboundOrderFx(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        return createOutboundOrder(requestMsg, responseMsg);

    }

    /**
     * 补充订单信息 取件时间
     * 
     * @param vo
     * @param warehouseService
     */
    private String supplementOrderVoTakeTime(String orderType, String warehouseCode) {
        if (OrderType.SP.getType().equals(orderType)) {
            QueryAutoTaketimeCommand command = new QueryAutoTaketimeCommand();
            command.setWarehouseCode(warehouseCode);
            try {
                String takeTime = upsWarehouseService.automaticPickUp(command);
                if (StringUtils.isEmpty(takeTime)) {
                    throw new ApiException(ErrorCode.TAKE_TIME_IS_EMPTY_ERROR);
                }
                return takeTime;
            } catch (Exception e) {
                throw new ApiException(ErrorCode.TAKE_TIME_IS_EMPTY_ERROR);
            }
        }
        return null;
    }

    private OutboundOrderCommand validAndBuildOrder(OutboundOrderVo vo) {
        OutboundOrderCommand command = new OutboundOrderCommand();
        // 构建取件时间
        String takeTime = supplementOrderVoTakeTime(vo.getProductInfo().getWinitProductCategory3(),
            vo.getDispatchWarehouseInfo().getWarehouseCode());
        vo.setTakeTime(takeTime);
        command.setOrder(vo);

        return command;

    }

}
